package znet

import (
	"fmt"
	"github.com/zinx/utils"
	"github.com/zinx/ziface"
	"net"
)

/**
* @Author: WuZhiHang
* @Date: 2020/10/15 9:53 下午
 */

// IServer 接口实现
type Server struct {
	// 服务器名称
	Name string
	// 服务器绑定的ip版本
	IPVersion string
	// 服务器监听的ip
	IP string
	// 服务器监听的端口
	Port int
	// 当前server消息管理模块，根据msgid来处理对应的路由
	MsgHandler ziface.IMsgHandle
}

// 启动服务器
func (s *Server) Start() {
	go func() {
		fmt.Printf("Start Server Listenner at Ip :%s, Port %d, is starting\n", s.IP, s.Port)
		// 创建一个TCP服务端
		addr, err := net.ResolveTCPAddr(s.IPVersion, fmt.Sprintf("%s:%d", s.IP, s.Port))
		if err != nil {
			// 如果出现失败，打印失败信息
			fmt.Println("resolve tcp addr error:", err)
			return
		}
		// 监听服务器地址
		listener, err := net.ListenTCP(s.IPVersion, addr)
		if err != nil {
			fmt.Println("ListenTCP error:", err)
			return
		}
		fmt.Println("start zinx server success")
		var cid uint32
		cid = 0
		// 阻塞等待客户端连接，处理客户端业务
		for {
			// 如果有客户端连接过来，阻塞
			conn, err := listener.AcceptTCP()
			if err != nil {
				fmt.Println("AcceptTCP err", err)
				continue
			}
			// 将处理新连接的业务方法和conn进行绑定 得到我们的连接模块
			dealConn := NewConnection(conn, cid, s.MsgHandler)
			cid++
			// 启动当前连接
			go dealConn.Start()
		}
	}()

}

// 停止服务器
func (s *Server) Stop() {
	// TODO 将服务器资源，状态等回收
}

// 运行服务器
func (s *Server) Serve() {

	// TODO 启动服务器之前的业务

	s.Start()

	// TODO 启动服务器之后的业务

	// 应该阻塞
	select {}
}

func (s *Server) AddRouter(msgId uint32, router ziface.IRouter) {
	s.MsgHandler.AddRouter(msgId, router)
}

// 初始化Server模块的方法
func NewServer(name string) ziface.IServer {
	return &Server{
		Name:       utils.GlobalObject.Name,
		IPVersion:  "tcp4",
		IP:         utils.GlobalObject.Host,
		Port:       utils.GlobalObject.TcpPort,
		MsgHandler: NewMsgHandle(),
	}
}
